//
//  VGTaskManager.swift
//  vgbox
//
//  Created by 宋海胜 on 2020/1/17.
//  Copyright © 2020 Swift Xcode. All rights reserved.
//

import UIKit
import SQLite

protocol VGTaskManagerProtocol {
    func runTask(_ dbModel: VGDBModel, progressClosure: ((Double) -> Void)?, successClosure: (() -> Void)?, failClosure: (() -> Void)?)
}

/// 任务管理器
class VGTaskManager: NSObject {
    
    public static let sharedInstance: VGTaskManager = VGTaskManager()
    
    public var delegate: VGTaskManagerProtocol!
    
    public var taskTable: Table!
    
    public var dbManager: VGDBManager = VGDBManager.sharedInstance
    
    public var progressNotiName: NSNotification.Name!
    
    public var refreshUINotiName: NSNotification.Name!
    
    public var failTryCount: Int = 10
    
    public var currentTryCount: Int = 0
    
    fileprivate var isRunning: Bool = false
    
    
    
    override init() {
        super.init()
    }

    public func addTask(_ model: VGDBModel) {
        
        let _ = dbManager.insertTasks(taskTable, model)
        if !isRunning {
            runTask()
        }
    }
    
    func deleteTask(_ rowId: Int64) {
        dbManager.deleteTask(taskTable, 0)
    }
    
    func updateTask(_ rowId: Int64, _ dbModel: VGDBModel) -> VGDBModel {
        dbManager.updateTasks(taskTable, rowId, dbModel)
        let ms: [VGDBModel] = dbManager.prepareTasksByRowId(taskTable, rowId)
        return ms.first!
    }
    
    func nextTask() {
        deleteTask(0)
        runTask()
    }
    
    func taskSuccessed() {
        self.taskRefreshUISignal()
        nextTask()
    }
    
    func taskFailed() {
        if failTryCount > currentTryCount {
            runTask()
            currentTryCount += 1
        } else {
            // 任务移至末尾
            let ms: [VGDBModel] = dbManager.prepareTasksByRowId(taskTable, 0)
            ms.first!.status = "fail"
            let _ = dbManager.insertTasks(taskTable, ms.first!)
            deleteTask(0)
            print("tableName:\(ms.first!.className) 任务失败")
            
            currentTryCount = 0
            runTask()
            currentTryCount += 1
        }
    }
    
    func taskProgressSignal(_ progress: Double) {
        NotificationCenter.default.post(name: progressNotiName, object: nil, userInfo: ["progress": progress])
    }
    
    func taskRefreshUISignal() {
        NotificationCenter.default.post(name: refreshUINotiName, object: self, userInfo:nil)
    }
    
    func runTask() {
        let tasks = dbManager.prepareTasksByRowId(taskTable, 0)
        if tasks.count > 0 {
            delegate.runTask(tasks.first!, progressClosure: { (progress) in
                self.taskProgressSignal(progress)
            }, successClosure: {
                self.taskSuccessed()
            }) {
                self.taskFailed()
            }
        }
    }
}
